--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tests/frontend/SriIntegrity.test.js 5764f8a060a65287966d5be310faef5eecd1d207 (5764f8a0) Text, 5.79 KB
Tff7b72import Tb4b4b4{ Te6edf3describeTb4b4b4, Te6edf3itTb4b4b4, Te6edf3expect Tb4b4b4} Tff7b72from Ta5d6ff"vitest"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3readFileSyncTb4b4b4, Te6edf3existsSync Tb4b4b4} Tff7b72from Ta5d6ff"fs"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3createHash Tb4b4b4} Tff7b72from Ta5d6ff"crypto"Tb4b4b4;
Tff7b72import Te6edf3path Tff7b72from Ta5d6ff"path"Tb4b4b4;
Tff7b72const Te6edf3REPO_ROOT Tff7b72= Te6edf3pathTb4b4b4.Te6edf3resolveTb4b4b4(Te6edf3__dirnameTb4b4b4, Ta5d6ff"../.."Tb4b4b4)Tb4b4b4;
Tff7b72function Te6edf3computeSri384Tb4b4b4(Te6edf3filePathTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3buf Tff7b72= Te6edf3readFileSyncTb4b4b4(Te6edf3filePathTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3hash Tff7b72= Te6edf3createHashTb4b4b4(Ta5d6ff"sha384"Tb4b4b4)Tb4b4b4.Te6edf3updateTb4b4b4(Te6edf3bufTb4b4b4)Tb4b4b4.Te6edf3digestTb4b4b4(Ta5d6ff"base64"Tb4b4b4)Tb4b4b4;
Tff7b72return Ta5d6ff`Ta5d6ffsha384-Tffd700${Te6edf3hashTffd700}Ta5d6ff`Tb4b4b4;
Tb4b4b4}
Te6edf3describeTb4b4b4(Ta5d6ff"SRI (Subresource Integrity) Verification"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3describeTb4b4b4(Ta5d6ff"micron-parser-go WASM"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"has valid integrity.json with matching SRI hashes"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3integrityPath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(
Te6edf3REPO_ROOTTb4b4b4,
Ta5d6ff"meshchatx/src/frontend/public/vendor/micron-parser-go/integrity.json"
Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3wasmPath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(
Te6edf3REPO_ROOTTb4b4b4,
Ta5d6ff"meshchatx/src/frontend/public/vendor/micron-parser-go/micron-parser-go.wasm"
Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3execPath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3REPO_ROOTTb4b4b4, Ta5d6ff"meshchatx/src/frontend/public/vendor/micron-parser-go/wasm_exec.js"Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3existsSyncTb4b4b4(Te6edf3integrityPathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72returnTb4b4b4; T8b949e// Skip if WASM not fetched
Tb4b4b4}
Tff7b72const Te6edf3integrity Tff7b72= Tffa657JSONTb4b4b4.Te6edf3parseTb4b4b4(Te6edf3readFileSyncTb4b4b4(Te6edf3integrityPathTb4b4b4, Ta5d6ff"utf-8"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3versionTb4b4b4)Tb4b4b4.Te6edf3toBeTruthyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3wasmTb4b4b4)Tb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/^sha384-[A-Za-z0-9+/=]+$/Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3wasmExecTb4b4b4)Tb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/^sha384-[A-Za-z0-9+/=]+$/Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3existsSyncTb4b4b4(Te6edf3wasmPathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3actualWasmHash Tff7b72= Te6edf3computeSri384Tb4b4b4(Te6edf3wasmPathTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3actualWasmHashTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3wasmTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3existsSyncTb4b4b4(Te6edf3execPathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3actualExecHash Tff7b72= Te6edf3computeSri384Tb4b4b4(Te6edf3execPathTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3actualExecHashTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3wasmExecTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3describeTb4b4b4(Ta5d6ff"Codec2 Emscripten"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"has valid integrity.json with all required files"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3integrityPath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(
Te6edf3REPO_ROOTTb4b4b4,
Ta5d6ff"meshchatx/src/frontend/public/assets/js/codec2-emscripten/integrity.json"
Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3baseDir Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3REPO_ROOTTb4b4b4, Ta5d6ff"meshchatx/src/frontend/public/assets/js/codec2-emscripten"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3existsSyncTb4b4b4(Te6edf3integrityPathTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3integrity Tff7b72= Tffa657JSONTb4b4b4.Te6edf3parseTb4b4b4(Te6edf3readFileSyncTb4b4b4(Te6edf3integrityPathTb4b4b4, Ta5d6ff"utf-8"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3versionTb4b4b4)Tb4b4b4.Te6edf3toBeTruthyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3filesTb4b4b4)Tb4b4b4.Te6edf3toBeTruthyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3requiredFiles Tff7b72= Tb4b4b4[
Ta5d6ff"c2dec.wasm"Tb4b4b4,
Ta5d6ff"c2dec.js"Tb4b4b4,
Ta5d6ff"c2enc.wasm"Tb4b4b4,
Ta5d6ff"c2enc.js"Tb4b4b4,
Ta5d6ff"sox.wasm"Tb4b4b4,
Ta5d6ff"sox.js"Tb4b4b4,
Ta5d6ff"codec2-lib.js"Tb4b4b4,
Ta5d6ff"codec2-microphone-recorder.js"Tb4b4b4,
Ta5d6ff"processor.js"Tb4b4b4,
Ta5d6ff"wav-encoder.js"Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3file Tff7b72of Te6edf3requiredFilesTb4b4b4) Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3filesTb4b4b4[Te6edf3fileTb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/^sha384-[A-Za-z0-9+/=]+$/Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3filePath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3baseDirTb4b4b4, Te6edf3fileTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3existsSyncTb4b4b4(Te6edf3filePathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3actualHash Tff7b72= Te6edf3computeSri384Tb4b4b4(Te6edf3filePathTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3actualHashTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3filesTb4b4b4[Te6edf3fileTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3describeTb4b4b4(Ta5d6ff"RNode Flasher"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"has valid integrity.json with all required vendor libraries"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3integrityPath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3REPO_ROOTTb4b4b4, Ta5d6ff"meshchatx/src/frontend/public/rnode-flasher/js/integrity.json"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3baseDir Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3REPO_ROOTTb4b4b4, Ta5d6ff"meshchatx/src/frontend/public/rnode-flasher/js"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3existsSyncTb4b4b4(Te6edf3integrityPathTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3integrity Tff7b72= Tffa657JSONTb4b4b4.Te6edf3parseTb4b4b4(Te6edf3readFileSyncTb4b4b4(Te6edf3integrityPathTb4b4b4, Ta5d6ff"utf-8"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3versionTb4b4b4)Tb4b4b4.Te6edf3toBeTruthyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3filesTb4b4b4)Tb4b4b4.Te6edf3toBeTruthyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3requiredFiles Tff7b72= Tb4b4b4[
Ta5d6ff"zip.min.js"Tb4b4b4,
Ta5d6ff"crypto-js@3.9.1-1/core.js"Tb4b4b4,
Ta5d6ff"crypto-js@3.9.1-1/md5.js"Tb4b4b4,
Ta5d6ff"esptool-js@0.4.5/bundle.js"Tb4b4b4,
Ta5d6ff"nrf52_dfu_flasher.js"Tb4b4b4,
Ta5d6ff"rnode.js"Tb4b4b4,
Ta5d6ff"web-serial-polyfill@1.0.15/dist/serial.js"Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3file Tff7b72of Te6edf3requiredFilesTb4b4b4) Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3filesTb4b4b4[Te6edf3fileTb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/^sha384-[A-Za-z0-9+/=]+$/Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3filePath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3baseDirTb4b4b4, Te6edf3fileTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3existsSyncTb4b4b4(Te6edf3filePathTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3actualHash Tff7b72= Te6edf3computeSri384Tb4b4b4(Te6edf3filePathTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3actualHashTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3integrityTb4b4b4.Te6edf3filesTb4b4b4[Te6edf3fileTb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3describeTb4b4b4(Ta5d6ff"SRI hash format validation"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"all SRI hashes use sha384- prefix and base64 format"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3integrityFiles Tff7b72= Tb4b4b4[
Ta5d6ff"meshchatx/src/frontend/public/vendor/micron-parser-go/integrity.json"Tb4b4b4,
Ta5d6ff"meshchatx/src/frontend/public/assets/js/codec2-emscripten/integrity.json"Tb4b4b4,
Ta5d6ff"meshchatx/src/frontend/public/rnode-flasher/js/integrity.json"Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3relPath Tff7b72of Te6edf3integrityFilesTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3fullPath Tff7b72= Te6edf3pathTb4b4b4.Te6edf3joinTb4b4b4(Te6edf3REPO_ROOTTb4b4b4, Te6edf3relPathTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3existsSyncTb4b4b4(Te6edf3fullPathTb4b4b4)Tb4b4b4) Tff7b72continueTb4b4b4;
Tff7b72const Te6edf3data Tff7b72= Tffa657JSONTb4b4b4.Te6edf3parseTb4b4b4(Te6edf3readFileSyncTb4b4b4(Te6edf3fullPathTb4b4b4, Ta5d6ff"utf-8"Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3hashes Tff7b72=
Te6edf3dataTb4b4b4.Te6edf3wasm Tff7b72&& Te6edf3dataTb4b4b4.Te6edf3wasmExec Tff7b72? Tb4b4b4[Te6edf3dataTb4b4b4.Te6edf3wasmTb4b4b4, Te6edf3dataTb4b4b4.Te6edf3wasmExecTb4b4b4] Tff7b72: Tffa657ObjectTb4b4b4.Te6edf3valuesTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3files Tff7b72|| Tb4b4b4{Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3hash Tff7b72of Te6edf3hashesTb4b4b4) Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3hashTb4b4b4)Tb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/^sha384-[A-Za-z0-9+/=]+$/Tb4b4b4)Tb4b4b4;
T8b949e// SHA-384 in base64 should be exactly 64 characters
Tff7b72const Te6edf3b64Part Tff7b72= Te6edf3hashTb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff"sha384-"Tb4b4b4, Ta5d6ff""Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3b64PartTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff64Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────